#pragma once

#include <AVUIEffectiveValueEntry.h>

namespace AVUI {

typedef ItemStructList< DependencyProperty* > DependencyPropertyList;

class FrameworkElement;
class FrameworkContentElement;
struct InheritablePropertyChangeInfo;
struct ResourcesChangeInfo;
struct TreeChangeInfo;
class Style;
struct ChildRecord;
class FrameworkObject;
class FrameworkPropertyMetadata;

class TreeWalkHelper
{
public:
#pragma region Internal Methods

    static bool HasChildren(FrameworkElement* pFE, FrameworkContentElement* pFCE);
    static void InvalidateOnInheritablePropertyChange(FrameworkElement* pFE, FrameworkContentElement* pFCE, InheritablePropertyChangeInfo info, bool skipStartNode);
    static void InvalidateOnResourcesChange(FrameworkElement* pFE, FrameworkContentElement* pFCE, ResourcesChangeInfo info);
    static void InvalidateOnTreeChange(FrameworkElement* pFE, FrameworkContentElement* pFCE, DependencyObject* pParent, bool isAddOperation);
    static TRefCountedPtr<DependencyPropertyList> InvalidateTreeDependentProperties(TreeChangeInfo info, FrameworkElement* pFE, FrameworkContentElement* pFCE, Style* pSelfStyle, Style* pSelfThemeStyle, ChildRecord* pChildRecord, bool isChildRecordValid, bool hasStyleChanged, bool isSelfInheritanceParent);
    static bool IsInheritanceNode(DependencyObject* pDO, DependencyProperty* pDP, InheritanceBehavior::Enum* pInheritanceBehavior);
    static bool IsInheritanceNode(FrameworkContentElement* pFCE, DependencyProperty* pDP, InheritanceBehavior::Enum* pInheritanceBehavior);
    static bool IsInheritanceNode(FrameworkElement* pFE, DependencyProperty* pDP, InheritanceBehavior::Enum* pInheritanceBehavior);
    static void OnInheritedPropertyChanged(DependencyObject* pDO, InheritablePropertyChangeInfo* pInfo, InheritanceBehavior::Enum inheritanceBehavior);
    static void OnResourcesChanged(DependencyObject* pDO, ResourcesChangeInfo info, bool raiseResourceChangedEvent);
    static bool SkipNext(InheritanceBehavior::Enum inheritanceBehavior);
    static bool SkipNow(InheritanceBehavior::Enum inheritanceBehavior);

#pragma endregion Internal Methods

private:

#pragma region Private Methods

    static void InvalidateResourceReferences(DependencyObject* pDO, ResourcesChangeInfo info);
    static void InvalidateStyleAndReferences(DependencyObject* pDO, ResourcesChangeInfo info, bool containsTypeOfKey);
    static bool InvalidateTreeDependentProperty(TreeChangeInfo info, DependencyObject* pDO, FrameworkObject* pFO, DependencyProperty* pDP, FrameworkPropertyMetadata* pFMetadata, Style* pSelfStyle, Style* pSelfThemeStyle, ChildRecord* pChildRecord, bool isChildRecordValid, bool hasStyleChanged, bool isSelfInheritanceParent);
    static bool IsForceInheritedProperty(DependencyProperty* pDP);
    static bool OnAncestorChanged(DependencyObject* pDO, TreeChangeInfo info);
    static void OnAncestorChanged(FrameworkElement* pFE, FrameworkContentElement* pFCE, TreeChangeInfo info);
    static bool OnInheritablePropertyChanged(DependencyObject* pDO, InheritablePropertyChangeInfo info);
    static bool OnPostAncestorChanged(DependencyObject* pDO, TreeChangeInfo info);
    static bool OnResourcesChangedCallback(DependencyObject* pDO, ResourcesChangeInfo info);

#pragma endregion Private Methods

};

};


